package com.tarena.lbs.basic.web.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import com.tarena.lbs.base.common.utils.Asserts;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.basic.web.dao.repository.AdminRepository;
import com.tarena.lbs.basic.web.dao.repository.BusinessRepository;
import com.tarena.lbs.basic.web.thread.AuthenticationUtil;
import com.tarena.lbs.common.passport.enums.Roles;
import com.tarena.lbs.common.passport.principle.UserPrinciple;
import com.tarena.lbs.pojo.basic.param.AdminParam;
import com.tarena.lbs.pojo.basic.po.AdminPO;
import com.tarena.lbs.pojo.basic.po.BusinessPO;
import com.tarena.lbs.pojo.basic.query.AdminQuery;
import com.tarena.lbs.pojo.basic.vo.AdminVO;
import com.tarena.lbs.pojo.basic.vo.BusinessVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AdminService {
    @Autowired
    private BusinessRepository businessRepository;

    @Autowired
    private AdminRepository adminRepository;
    public AdminVO detail() throws BusinessException {
        //作为过滤器的执行代码的下游逻辑 可以直接在threadLocal获取数据
        //在业务层获取到的数据 就是本次请求的认证对象
        UserPrinciple userPrinciple = getAuthentication();
        //不一定能拿到认证对象 抛异常
        Asserts.isTrue(userPrinciple==null,new BusinessException("-2","认证解析失败"));
        Integer id = userPrinciple.getId();
        //1.查询adminPO
        AdminPO po = adminRepository.getById(id);
        AdminVO vo = null;
        if (po != null) {
            vo = new AdminVO();
            BeanUtils.copyProperties(po, vo);
        }
        return vo;
    }

    private UserPrinciple getAuthentication() {
        return AuthenticationUtil.get();
    }

    public PageResult<AdminVO> accountPage(AdminQuery adminQuery) {
        //封装前端入参查询页数+页码
        PageResult<AdminVO> voPage = new PageResult<>();
        voPage.setPageSize(adminQuery.getPageSize());
        voPage.setPageNo(adminQuery.getPageNo());
        //调用数据层查询账号详情
        PageInfo<AdminPO> pageInfo = adminRepository.accountPage(adminQuery);
        voPage.setTotal(pageInfo.getTotal());
        List<AdminPO> pos = pageInfo.getList();
        //封装vos 使用list的stream() api forEach filter map sort...
        List<AdminVO> vos = null;
        if (pos != null && pos.size()>0) {
            vos = pos.stream().map(po->{
                //映射计算 每一个po元素转化成vo
                AdminVO vo = new AdminVO();
                BeanUtils.copyProperties(po,vo);
                return vo;
            }).collect(Collectors.toList());
        }
        voPage.setObjects(vos);
        return voPage;
    }
@Transactional(rollbackFor = Exception.class)
    public void save(AdminParam adminParam) throws BusinessException {
        //1.检验业务权限 是否满足用户角色=Roles.admin
        CheckRole(Roles.ADMIN);
        //2.查询商家是否存在
        checkBusinessExist(adminParam);
        //3.保证幂等
        Mideng(adminParam);
        //4.封装po 调用仓储层写入
        AdminPO poParam = param2po(adminParam);
        log.debug("新增写入之前,po的id:{}",poParam.getId());
        adminRepository.save(poParam);
        log.debug("新增写入之后,po的id:{}",poParam.getId());
    }

    private void checkBusinessExist(AdminParam adminParam) throws BusinessException {
        if(adminParam.getAccountType()==1){
            BusinessPO business = businessRepository.getBusiness(adminParam.getBusinessId());
            Asserts.isTrue(business == null,new BusinessException("-2","商家不存在"));
        }
    }

    private AdminPO param2po(AdminParam adminParam) {
        AdminPO po = new AdminPO();
        BeanUtils.copyProperties(adminParam,po);
        po.setCreateTime(new Date());
        //平台用户不需绑定商家id
        if(po.getAccountType()==0){
            po.setBusinessId(0);
        }
        return po;
    }

    private void Mideng(AdminParam adminParam) throws BusinessException {
        String accountPhone = adminParam.getAccountPhone();
        String email = adminParam.getEmail();
        if(accountPhone!=null){
            QueryWrapper<AdminPO> wq = new QueryWrapper<>();
            wq.eq("account_phone",accountPhone);
            long count = adminRepository.count(wq);
            Asserts.isTrue(count>0,new BusinessException("-2","手机号已存在"));
        }
        if (email != null) {
            QueryWrapper<AdminPO> wq = new QueryWrapper<>();
            wq.eq("email",email);
            long count = adminRepository.count(wq);
            Asserts.isTrue(count>0,new BusinessException("-2","邮箱已存在"));
        }
    }

    private void CheckRole(Roles roles) throws BusinessException {
        //1.拿到登录用身份
        UserPrinciple userPrinciple = AuthenticationUtil.get();
        //2.断言 拿不到
        Asserts.isTrue(userPrinciple==null,new BusinessException("-2","认证解析失败"));
        //3.断言 登录身份和要求身份是否一致
        Asserts.isTrue(!(userPrinciple.getRole()==roles),new BusinessException("-2","权限不足"));
    }
}
